package com.zhichat.web.socket;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @ClassName: ChannelContextCommon
 * @Description: channel上下文公共类（处理业务需要的各种场景）
 * @Author: 团长九哥 https://space.bilibili.com/602197686
 * @CreateDate: 2024/12/1 10:57
 */
@Slf4j
@Component
@AllArgsConstructor
public class ChannelContextCommon {

    private static final ConcurrentHashMap<Long, Channel> USER_CHANNEL_MAP = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Long, ChannelGroup> GROUP_CHANNEL_MAP = new ConcurrentHashMap<>();

    /**
     * 根据用户id获取用户channel
     */
    public Channel getUserChannel(Long userId) {
        if (Objects.isNull(userId)) {
            return null;
        }
        return USER_CHANNEL_MAP.get(userId) == null ? null : USER_CHANNEL_MAP.get(userId);
    }

    /**
     * 将 channel(用户channel) 存储到 USER_CHANNEL_MAP(用户channelMap) 中
     */
    public void setUserChannel(Long userId, Channel channel) {
        if (ObjectUtil.hasNull(userId, channel)) {
            return;
        }
        USER_CHANNEL_MAP.put(userId, channel);
    }

    /**
     * 根据群组id获取群组channelGroup
     */
    public ChannelGroup getChannelGroup(Long groupId) {
        if (Objects.isNull(groupId)) {
            return null;
        }
        return GROUP_CHANNEL_MAP.get(groupId);
    }

    /**
     * 根据群组id获取群组channelGroup
     */
    public void setChannelGroup(Long groupId) {
        if (Objects.isNull(groupId)) {
            return;
        }
        ChannelGroup channelGroup = GROUP_CHANNEL_MAP.get(groupId);
        if (Objects.isNull(channelGroup)) {
            channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
            GROUP_CHANNEL_MAP.put(groupId, channelGroup);
        }
    }

    /**
     * 将 channel(用户channel) 存储到对应 groupId(群组ID) 的 channelGroup(群组ChannelGroup) 中
     */
    public void putAllUserChannelToGroupChannel(Long groupId, List<Channel> userChannelList) {
        if (ObjectUtil.hasNull(userChannelList, groupId) || CollUtil.isEmpty(userChannelList)) {
            return;
        }
        ChannelGroup channelGroup = GROUP_CHANNEL_MAP.get(groupId);
        if (Objects.isNull(channelGroup)) {
            channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
            GROUP_CHANNEL_MAP.put(groupId, channelGroup);
        }
        channelGroup.addAll(userChannelList);
    }

    /**
     * 将 channel(用户channel) 存储到对应 groupId(群组ID) 的 channelGroup(群组ChannelGroup) 中
     */
    public void delAllUserChannelToGroupChannel(Long groupId, List<Channel> userChannelList) {
        if (ObjectUtil.hasNull(userChannelList, groupId) || CollUtil.isEmpty(userChannelList)) {
            return;
        }
        ChannelGroup channelGroup = GROUP_CHANNEL_MAP.get(groupId);
        if (Objects.isNull(channelGroup)) {
            return;
        }
        userChannelList.forEach(channelGroup::remove);
    }

    /**
     * 用户下线，移除对应的channel数据
     */
    public void removeUserChannel(Long userId) {
        if (Objects.isNull(userId)) {
            return;
        }
        Channel channel = USER_CHANNEL_MAP.get(userId);
        if (Objects.nonNull(channel)) {
            channel.close();
        }
        USER_CHANNEL_MAP.remove(userId);
    }

    /**
     * 群组解散，移除对应的channelGroup数据
     */
    public void removeGroupChannel(Long groupId) {
        if (Objects.isNull(groupId)) {
            return;
        }
        ChannelGroup channelGroup = GROUP_CHANNEL_MAP.get(groupId);
        if (Objects.nonNull(channelGroup)) {
            channelGroup.close();
        }
        GROUP_CHANNEL_MAP.remove(groupId);
    }
}
